﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SisCRA.Business;
using SisCRA.Classes;

namespace SisCRA.Forms
{
    public partial class FormGradesAndFaults : Form
    {
        #region -Constructor-

        /// <summary>
        /// Construtor padrão.
        /// </summary>
        public FormGradesAndFaults()
        {
            try
            {
                InitializeComponent();
                LoadComboBoxSearchDiscipline();
                LoadDataGridViewStudentsEnrollment();
                LoadComboBoxActivity();
            }
            catch (Exception ex)
            {
                Log.Instance.Error(ex);
                MessageBox.Show(this, "Falha ao buscar dados.\r\nPor favor, verifique suas configurações de conexão com o banco de dados.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region -Events-

        private void comboBoxSearchDiscipline_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                LoadDataGridViewStudentsEnrollment();
                LoadComboBoxActivity();
            }
            catch
            {

            }
        }

        private void dataGridViewStudentsEnrollment_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                LoadFaults();
                LoadGrades();
            }
            catch
            {
 
            }
        }

        private void comboBoxActivity_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                LoadGrades();
            }
            catch
            {
 
            }
        }

        private void textBoxGrades_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(char.IsNumber(e.KeyChar) || char.IsControl(e.KeyChar) || (e.KeyChar.Equals(',') && !textBoxGrades.Text.Contains(','))))
            {
                e.Handled = true;
            }
        }

        private void textBoxFaults_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(char.IsNumber(e.KeyChar) || char.IsControl(e.KeyChar)))
            {
                e.Handled = true;
            }
        }

        private void buttonGrades_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(textBoxGrades.Text) || double.Parse(textBoxGrades.Text) > 10)
                {
                    MessageBox.Show(this, "Existem campos inválidos!", "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    StudentEnrollmentAvaliation studentEnrollmentAvaliation = new StudentEnrollmentAvaliation();
                    studentEnrollmentAvaliation.StudentId = int.Parse(this.dataGridViewStudentsEnrollment.SelectedRows[0].Cells[0].Value.ToString());
                    studentEnrollmentAvaliation.DisciplineId = (int)this.comboBoxSearchDiscipline.SelectedValue;
                    studentEnrollmentAvaliation.ActivityId = (int)this.comboBoxActivity.SelectedValue;
                    studentEnrollmentAvaliation.Grade = double.Parse(textBoxGrades.Text);

                    StudentEnrollmentAvaliationBLL studentEnrollmentAvaliationBLL = new StudentEnrollmentAvaliationBLL();
                    studentEnrollmentAvaliationBLL.SaveStudentEnrollmentAvaliation(studentEnrollmentAvaliation);

                    // Envia e-mail de aviso de notas.
                    Mail.Instance.SendGradesMail(studentEnrollmentAvaliation);

                    MessageBox.Show(this, "Nota salva com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error(ex);
                MessageBox.Show(this, "Falha ao salvar a disciplina.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonFaults_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(textBoxFaults.Text))
                {
                    MessageBox.Show(this, "Existem campos inválidos!", "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    StudentEnrollment studentEnrollment = new StudentEnrollment();
                    studentEnrollment.StudentId = int.Parse(this.dataGridViewStudentsEnrollment.SelectedRows[0].Cells[0].Value.ToString());
                    studentEnrollment.DisciplineId = (int)this.comboBoxSearchDiscipline.SelectedValue;
                    studentEnrollment.Faults = int.Parse(textBoxFaults.Text);

                    StudentEnrollmentBLL studentEnrollmentBLL = new StudentEnrollmentBLL();
                    studentEnrollmentBLL.SaveStudentFaults(studentEnrollment);

                    // Envia e-mail de alerta de faltas.
                    Mail.Instance.SendFaultsMail(studentEnrollment);

                    MessageBox.Show(this, "Faltas salvas com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error(ex);
                MessageBox.Show(this, "Falha ao salvar a disciplina.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonClosingGrades_Click(object sender, EventArgs e)
        {
            try
            {
                if (DialogResult.Yes == MessageBox.Show(this, "Deseja realmente fechar as notas dessa disciplina?", "Fechar Notas", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
                {
                    // Id da disciplina selecionada.
                    int disciplineId = (int)this.comboBoxSearchDiscipline.SelectedValue;

                    // Camadas de lógica de negócios.
                    ActivityBLL activityBLL = new ActivityBLL();
                    StudentEnrollmentBLL studentEnrollmentBLL = new StudentEnrollmentBLL();
                    StudentEnrollmentAvaliationBLL studentEnrollmentAvaliationBLL = new StudentEnrollmentAvaliationBLL();

                    Activity activity = new Activity();
                    activity.DisciplineId = disciplineId;

                    // Verificando se a soma dos pesos das atividades somam 100%.
                    if (activityBLL.IsPercentage100(activity))
                    {
                        StudentEnrollmentAvaliation studentEnrollmentAvaliation = new StudentEnrollmentAvaliation();
                        studentEnrollmentAvaliation.DisciplineId = disciplineId;

                        // Verificando se as notas dos alunos em todas as atividades foram cadastradas.
                        if (studentEnrollmentAvaliationBLL.IsGradesOk(studentEnrollmentAvaliation))
                        {
                            Discipline discipline = new Discipline();
                            discipline.Id = disciplineId;

                            // Buscando todos os alunos da disciplina selecionada.
                            DataTable dtStudentEnrollment = studentEnrollmentBLL.GetAllStudentByDiscipline(discipline);

                            foreach (DataRow drStudentEnrollment in dtStudentEnrollment.Rows)
                            {
                                // Id de cada aluno da disciplina selecionada.
                                int studentId = int.Parse(drStudentEnrollment["ID"].ToString());

                                // Buscando as notas e os pesos de cada atividade para calcular a média final.
                                studentEnrollmentAvaliation.StudentId = studentId;
                                DataTable dtAvaliation = studentEnrollmentAvaliationBLL.GetAvaliationByStudentAndDiscipline(studentEnrollmentAvaliation);

                                // Calculando a média final.
                                double finalGrade = 0;

                                foreach (DataRow drAvaliation in dtAvaliation.Rows)
                                {
                                    finalGrade += double.Parse(drAvaliation["PESO"].ToString()) * double.Parse(drAvaliation["NOTA"].ToString());
                                }

                                finalGrade /= 100.0;

                                StudentEnrollment studentEnrollment = new StudentEnrollment();
                                studentEnrollment.StudentId = studentId;
                                studentEnrollment.DisciplineId = disciplineId;
                                studentEnrollment.FinalGrade = finalGrade;

                                // Atualizando a média final e a situação do aluno.
                                studentEnrollmentBLL.SaveStudentFinalGradeAndSituation(studentEnrollment);
                            }

                            MessageBox.Show(this, "Notas fechadas com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            MessageBox.Show(this, "Para realizar o fechamento de notas dessa disciplina as notas de todos os alunos em todas as atividades devem estar cadastradas!", "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                    }
                    else
                    {
                        MessageBox.Show(this, "Para realizar o fechamento de notas dessa disciplina os pesos das atividades devem somar 100%! Acesse a opção 'Cadasto de Atividades' e altere os pesos das atividades dessa disciplina.", "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error(ex);
                MessageBox.Show(this, "Falha ao fechar notas.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

        #endregion

        #region -Private Methods-

        /// <summary>
        /// Método que carrega o comboBoxSearchDiscipline.
        /// </summary>
        private void LoadComboBoxSearchDiscipline()
        {
            try
            {
                DisciplineBLL disciplineBLL = new DisciplineBLL();
                this.comboBoxSearchDiscipline.DataSource = disciplineBLL.GetAllDiscipline();
                this.comboBoxSearchDiscipline.ValueMember = "ID";
                this.comboBoxSearchDiscipline.DisplayMember = "CODIGO";
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que carrega o dataGridViewStudentsEnrollment.
        /// </summary>
        private void LoadDataGridViewStudentsEnrollment()
        {
            try
            {
                Discipline discipline = new Discipline();
                discipline.Id = (int)this.comboBoxSearchDiscipline.SelectedValue;

                StudentEnrollmentBLL studentEnrollmentBLL = new StudentEnrollmentBLL();
                this.dataGridViewStudentsEnrollment.DataSource = studentEnrollmentBLL.GetAllStudentByDiscipline(discipline);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que carrega o comboBoxActivity.
        /// </summary>
        private void LoadComboBoxActivity()
        {
            try
            {
                Activity activity = new Activity();
                activity.DisciplineId = (int)this.comboBoxSearchDiscipline.SelectedValue;

                ActivityBLL activityBLL = new ActivityBLL();
                this.comboBoxActivity.DataSource = activityBLL.GetAllActivityByDiscipline(activity);
                this.comboBoxActivity.ValueMember = "ID";
                this.comboBoxActivity.DisplayMember = "NOME";
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que carrega a nota de um aluno 
        /// </summary>
        private void LoadGrades()
        {
            try
            {
                if (this.dataGridViewStudentsEnrollment.SelectedRows.Count == 1)
                {
                    StudentEnrollmentAvaliation studentEnrollmentAvaliation = new StudentEnrollmentAvaliation();
                    studentEnrollmentAvaliation.StudentId = int.Parse(this.dataGridViewStudentsEnrollment.SelectedRows[0].Cells[0].Value.ToString());
                    studentEnrollmentAvaliation.DisciplineId = (int)this.comboBoxSearchDiscipline.SelectedValue;
                    studentEnrollmentAvaliation.ActivityId = (int)this.comboBoxActivity.SelectedValue;

                    StudentEnrollmentAvaliationBLL studentEnrollmentAvaliationBLL = new StudentEnrollmentAvaliationBLL();
                    DataTable dtStudentEnrollmentAvaliation = studentEnrollmentAvaliationBLL.GetStudentEnrollmentAvaliation(studentEnrollmentAvaliation);

                    if (dtStudentEnrollmentAvaliation.Rows.Count > 0)
                    {
                        textBoxGrades.Text = dtStudentEnrollmentAvaliation.Rows[0][3].ToString();
                    }
                    else
                    {
                        CleanGrades();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que carrega as faltas de um aluno em uma disciplina.
        /// </summary>
        private void LoadFaults()
        {
            try
            {
                if (this.dataGridViewStudentsEnrollment.SelectedRows.Count == 1)
                {
                    StudentEnrollment studentEnrollment = new StudentEnrollment();
                    studentEnrollment.StudentId = int.Parse(this.dataGridViewStudentsEnrollment.SelectedRows[0].Cells[0].Value.ToString());
                    studentEnrollment.DisciplineId = (int)this.comboBoxSearchDiscipline.SelectedValue;

                    StudentEnrollmentBLL studentEnrollmentBLL = new StudentEnrollmentBLL();
                    textBoxFaults.Text = studentEnrollmentBLL.GetStudentEnroll(studentEnrollment).Rows[0][2].ToString();
                }
                else
                {
                    CleanGrades();
                    CleanFaults();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que limpa o campo de nota do formulário.
        /// </summary>
        private void CleanGrades()
        {
            this.textBoxGrades.Text = string.Empty;
        }

        /// <summary>
        /// Método que limpa o campo de faltas do formulário.
        /// </summary>
        private void CleanFaults()
        {
            this.textBoxFaults.Text = string.Empty;
        }

        #endregion
    }
}
